/*
 * Copyright 2012 - 2013 Benjamin Weiss
 * Copyright 2012 Neofonie Mobile GmbH
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package de.keyboardsurfer.android.widget.crouton;

import android.graphics.drawable.Drawable;
import android.view.Gravity;
import android.view.ViewGroup.LayoutParams;
import android.widget.ImageView;

/** The style for a {@link Crouton}. */
public class CroutonStyle {

	public static final int holoRedLight = 0xffff4444;
	public static final int holoGreenLight = 0xff99cc00;
	public static final int holoBlueLight = 0xff33b5e5;
	public static final int holoOrangeLight = 0xffffbb33;

	/** Default style for alerting the user. */
	public static final CroutonStyle ALERT;
	/** Default style for warn the user. */
	public static final CroutonStyle WARN;
	/** Default style for confirming an action. */
	public static final CroutonStyle CONFIRM;
	/** Default style for general information. */
	public static final CroutonStyle INFO;

	static {
		ALERT = new Builder().setBackgroundColorValue(holoRedLight).build();
		WARN = new Builder().setBackgroundColorValue(holoOrangeLight).build();
		CONFIRM = new Builder().setBackgroundColorValue(holoGreenLight).build();
		INFO = new Builder().setBackgroundColorValue(holoBlueLight).build();
	}

	/**
	 * The {@link CroutonConfiguration} for this {@link CroutonStyle}. It can be
	 * overridden via {@link Crouton#setConfiguration(CroutonConfiguration)}.
	 */
	final CroutonConfiguration configuration;

	/**
	 * The resource id of the backgroundResourceId.
	 * <p/>
	 * 0 for no backgroundResourceId.
	 */
	final int backgroundColorResourceId;

	/**
	 * The resource id of the backgroundDrawableResourceId.
	 * <p/>
	 * 0 for no backgroundDrawableResourceId.
	 */
	final int backgroundDrawableResourceId;

	/**
	 * The backgroundColorResourceValue's e.g. 0xffff4444;
	 * <p/>
	 * -1 for no value.
	 */
	final int backgroundColorValue;

	/** Whether we should isTileEnabled the backgroundResourceId or not. */
	final boolean isTileEnabled;

	/**
	 * The text colorResourceId's resource id.
	 * <p/>
	 * 0 sets the text colorResourceId to the system theme default.
	 */
	final int textColorResourceId;

	/** The height of the {@link Crouton} in pixels. */
	final int heightInPixels;

	/** Resource ID for the height of the {@link Crouton}. */
	final int heightDimensionResId;

	/** The width of the {@link Crouton} in pixels. */
	final int widthInPixels;

	/** Resource ID for the width of the {@link Crouton}. */
	final int widthDimensionResId;

	/** The text's gravity as provided by {@link Gravity}. */
	final int gravity;

	/** An additional image to display in the {@link Crouton}. */
	final Drawable imageDrawable;

	/** An additional image to display in the {@link Crouton}. */
	final int imageResId;

	/**
	 * The {@link ImageView.ScaleType} for the image to display in the
	 * {@link Crouton}.
	 */
	final ImageView.ScaleType imageScaleType;

	/**
	 * The text size in sp
	 * <p/>
	 * 0 sets the text size to the system theme default
	 */
	final int textSize;

	/** The text shadow color's resource id */
	final int textShadowColorResId;

	/** The text shadow radius */
	final float textShadowRadius;

	/** The text shadow vertical offset */
	final float textShadowDy;

	/** The text shadow horizontal offset */
	final float textShadowDx;

	/** The text appearance resource id for the text. */
	final int textAppearanceResId;

	/** The padding for the crouton view content in pixels */
	final int paddingInPixels;

	/** The resource id for the padding for the view content */
	final int paddingDimensionResId;

	private CroutonStyle(final Builder builder) {
		configuration = builder.configuration;
		backgroundColorResourceId = builder.backgroundColorResourceId;
		backgroundDrawableResourceId = builder.backgroundDrawableResourceId;
		isTileEnabled = builder.isTileEnabled;
		textColorResourceId = builder.textColorResourceId;
		heightInPixels = builder.heightInPixels;
		heightDimensionResId = builder.heightDimensionResId;
		widthInPixels = builder.widthInPixels;
		widthDimensionResId = builder.widthDimensionResId;
		gravity = builder.gravity;
		imageDrawable = builder.imageDrawable;
		textSize = builder.textSize;
		textShadowColorResId = builder.textShadowColorResId;
		textShadowRadius = builder.textShadowRadius;
		textShadowDx = builder.textShadowDx;
		textShadowDy = builder.textShadowDy;
		textAppearanceResId = builder.textAppearanceResId;
		imageResId = builder.imageResId;
		imageScaleType = builder.imageScaleType;
		paddingInPixels = builder.paddingInPixels;
		paddingDimensionResId = builder.paddingDimensionResId;
		backgroundColorValue = builder.backgroundColorValue;
	}

	@Override
	public String toString() {
		return "Style{" + "configuration=" + configuration + ", backgroundColorResourceId=" + backgroundColorResourceId
				+ ", backgroundDrawableResourceId=" + backgroundDrawableResourceId + ", backgroundColorValue="
				+ backgroundColorValue + ", isTileEnabled=" + isTileEnabled + ", textColorResourceId="
				+ textColorResourceId + ", heightInPixels=" + heightInPixels + ", heightDimensionResId="
				+ heightDimensionResId + ", widthInPixels=" + widthInPixels + ", widthDimensionResId="
				+ widthDimensionResId + ", gravity=" + gravity + ", imageDrawable=" + imageDrawable + ", imageResId="
				+ imageResId + ", imageScaleType=" + imageScaleType + ", textSize=" + textSize
				+ ", textShadowColorResId=" + textShadowColorResId + ", textShadowRadius=" + textShadowRadius
				+ ", textShadowDy=" + textShadowDy + ", textShadowDx=" + textShadowDx + ", textAppearanceResId="
				+ textAppearanceResId + ", paddingInPixels=" + paddingInPixels + ", paddingDimensionResId="
				+ paddingDimensionResId + '}';
	}

	/** Builder for the {@link CroutonStyle} object. */
	public static class Builder {
		private CroutonConfiguration configuration;
		private int backgroundColorValue;
		private int backgroundColorResourceId;
		private int backgroundDrawableResourceId;
		private boolean isTileEnabled;
		private int textColorResourceId;
		private int heightInPixels;
		private int heightDimensionResId;
		private int widthInPixels;
		private int widthDimensionResId;
		private int gravity;
		private Drawable imageDrawable;
		private int textSize;
		private int textShadowColorResId;
		private float textShadowRadius;
		private float textShadowDx;
		private float textShadowDy;
		private int textAppearanceResId;
		private int imageResId;
		private ImageView.ScaleType imageScaleType;
		private int paddingInPixels;
		private int paddingDimensionResId;

		/** Creates a {@link Builder} to build a {@link CroutonStyle} upon. */
		public Builder() {
			configuration = CroutonConfiguration.DEFAULT;
			paddingInPixels = 10;
			backgroundColorResourceId = android.R.color.holo_blue_light;
			backgroundDrawableResourceId = 0;
			backgroundColorValue = -1;
			isTileEnabled = false;
			textColorResourceId = android.R.color.white;
			heightInPixels = LayoutParams.WRAP_CONTENT;
			widthInPixels = LayoutParams.MATCH_PARENT;
			gravity = Gravity.CENTER;
			imageDrawable = null;
			imageResId = 0;
			imageScaleType = ImageView.ScaleType.FIT_XY;
		}

		/**
		 * Creates a {@link Builder} to build a {@link CroutonStyle} upon.
		 * 
		 * @param baseStyle The base {@link CroutonStyle} to use for this
		 *            {@link CroutonStyle} .
		 */
		public Builder(final CroutonStyle baseStyle) {
			configuration = baseStyle.configuration;
			backgroundColorValue = baseStyle.backgroundColorValue;
			backgroundColorResourceId = baseStyle.backgroundColorResourceId;
			backgroundDrawableResourceId = baseStyle.backgroundDrawableResourceId;
			isTileEnabled = baseStyle.isTileEnabled;
			textColorResourceId = baseStyle.textColorResourceId;
			heightInPixels = baseStyle.heightInPixels;
			heightDimensionResId = baseStyle.heightDimensionResId;
			widthInPixels = baseStyle.widthInPixels;
			widthDimensionResId = baseStyle.widthDimensionResId;
			gravity = baseStyle.gravity;
			imageDrawable = baseStyle.imageDrawable;
			textSize = baseStyle.textSize;
			textShadowColorResId = baseStyle.textShadowColorResId;
			textShadowRadius = baseStyle.textShadowRadius;
			textShadowDx = baseStyle.textShadowDx;
			textShadowDy = baseStyle.textShadowDy;
			textAppearanceResId = baseStyle.textAppearanceResId;
			imageResId = baseStyle.imageResId;
			imageScaleType = baseStyle.imageScaleType;
			paddingInPixels = baseStyle.paddingInPixels;
			paddingDimensionResId = baseStyle.paddingDimensionResId;
		}

		/** @return a configured {@link CroutonStyle} object. */
		public CroutonStyle build() {
			return new CroutonStyle(this);
		}

		/**
		 * Set the backgroundColorResourceId option of the {@link Crouton}.
		 * 
		 * @param backgroundColorResourceId The backgroundColorResourceId's
		 *            resource id.
		 * @return the {@link Builder}.
		 */
		public Builder setBackgroundColor(final int backgroundColorResourceId) {
			this.backgroundColorResourceId = backgroundColorResourceId;

			return this;
		}

		/**
		 * Set the backgroundColorResourceValue option of the {@link Crouton}.
		 * 
		 * @param backgroundColorValue The backgroundColorResourceValue's e.g.
		 *            0xffff4444;
		 * @return the {@link Builder}.
		 */
		public Builder setBackgroundColorValue(final int backgroundColorValue) {
			this.backgroundColorValue = backgroundColorValue;
			return this;
		}

		/**
		 * Set the backgroundDrawableResourceId option for the {@link Crouton}.
		 * 
		 * @param backgroundDrawableResourceId Resource ID of a
		 *            backgroundDrawableResourceId image drawable.
		 * @return the {@link Builder}.
		 */
		public Builder setBackgroundDrawable(final int backgroundDrawableResourceId) {
			this.backgroundDrawableResourceId = backgroundDrawableResourceId;

			return this;
		}

		/**
		 * Set the {@link CroutonConfiguration} option of the {@link Crouton}.
		 * 
		 * @param configuration The {@link CroutonConfiguration}.
		 * @return the {@link Builder}.
		 */
		public Builder setConfiguration(final CroutonConfiguration configuration) {
			this.configuration = configuration;
			return this;
		}

		/**
		 * Set the gravity option for the {@link Crouton}.
		 * 
		 * @param gravity The text's gravity as provided by {@link Gravity}.
		 * @return the {@link Builder}.
		 */
		public Builder setGravity(final int gravity) {
			this.gravity = gravity;

			return this;
		}

		/**
		 * Set the heightInPixels option for the {@link Crouton}.
		 * 
		 * @param height The height of the {@link Crouton} in pixel. Can also be
		 *            {@link LayoutParams#MATCH_PARENT} or
		 *            {@link LayoutParams#WRAP_CONTENT}.
		 * @return the {@link Builder}.
		 */
		public Builder setHeight(final int height) {
			heightInPixels = height;

			return this;
		}

		/**
		 * Set the resource id for the height option for the {@link Crouton}.
		 * 
		 * @param heightDimensionResId Resource ID of a dimension for the height
		 *            of the {@link Crouton}.
		 * @return the {@link Builder}.
		 */
		public Builder setHeightDimensionResId(final int heightDimensionResId) {
			this.heightDimensionResId = heightDimensionResId;

			return this;
		}

		/**
		 * Set the image option for the {@link Crouton}.
		 * 
		 * @param imageDrawable An additional image to display in the
		 *            {@link Crouton}.
		 * @return the {@link Builder}.
		 */
		public Builder setImageDrawable(final Drawable imageDrawable) {
			this.imageDrawable = imageDrawable;

			return this;
		}

		/**
		 * Set the image resource option for the {@link Crouton}.
		 * 
		 * @param imageResId An additional image to display in the
		 *            {@link Crouton}.
		 * @return the {@link Builder}.
		 */
		public Builder setImageResource(final int imageResId) {
			this.imageResId = imageResId;

			return this;
		}

		/** The {@link android.widget.ImageView.ScaleType} for the image. */
		public Builder setImageScaleType(final ImageView.ScaleType imageScaleType) {
			this.imageScaleType = imageScaleType;
			return this;
		}

		/** The resource id for the padding for the crouton view's content. */
		public Builder setPaddingDimensionResId(final int paddingResId) {
			paddingDimensionResId = paddingResId;
			return this;
		}

		/** The padding for the crouton view's content in pixels. */
		public Builder setPaddingInPixels(final int padding) {
			paddingInPixels = padding;
			return this;
		}

		/** The text appearance resource id for the text. */
		public Builder setTextAppearance(final int textAppearanceResId) {
			this.textAppearanceResId = textAppearanceResId;
			return this;
		}

		/**
		 * Set the textColorResourceId option for the {@link Crouton}.
		 * 
		 * @param textColor The resource id of the text colorResourceId.
		 * @return the {@link Builder}.
		 */
		public Builder setTextColor(final int textColor) {
			textColorResourceId = textColor;

			return this;
		}

		/** The text shadow color resource id. */
		public Builder setTextShadowColor(final int textShadowColorResId) {
			this.textShadowColorResId = textShadowColorResId;
			return this;
		}

		/** The text shadow horizontal offset. */
		public Builder setTextShadowDx(final float textShadowDx) {
			this.textShadowDx = textShadowDx;
			return this;
		}

		/** The text shadow vertical offset. */
		public Builder setTextShadowDy(final float textShadowDy) {
			this.textShadowDy = textShadowDy;
			return this;
		}

		/** The text shadow radius. */
		public Builder setTextShadowRadius(final float textShadowRadius) {
			this.textShadowRadius = textShadowRadius;
			return this;
		}

		/** The text size in sp. */
		public Builder setTextSize(final int textSize) {
			this.textSize = textSize;
			return this;
		}

		/**
		 * Set the isTileEnabled option for the {@link Crouton}.
		 * 
		 * @param isTileEnabled <code>true</code> if you want the
		 *            backgroundResourceId to be tiled, else <code>false</code>.
		 * @return the {@link Builder}.
		 */
		public Builder setTileEnabled(final boolean isTileEnabled) {
			this.isTileEnabled = isTileEnabled;

			return this;
		}

		/**
		 * Set the widthInPixels option for the {@link Crouton}.
		 * 
		 * @param width The width of the {@link Crouton} in pixel. Can also be
		 *            {@link LayoutParams#MATCH_PARENT} or
		 *            {@link LayoutParams#WRAP_CONTENT}.
		 * @return the {@link Builder}.
		 */
		public Builder setWidth(final int width) {
			widthInPixels = width;

			return this;
		}

		/**
		 * Set the resource id for the width option for the {@link Crouton}.
		 * 
		 * @param widthDimensionResId Resource ID of a dimension for the width
		 *            of the {@link Crouton}.
		 * @return the {@link Builder}.
		 */
		public Builder setWidthDimensionResId(final int widthDimensionResId) {
			this.widthDimensionResId = widthDimensionResId;

			return this;
		}
	}
}
